﻿using System.Linq;
using ChiWalker.Dynamics;
using ChiWalker.Helpers;
using ChiWalker.Settings;
using ChiWalker.Spell;
using ChiWalker.Utilities;
using Styx;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

namespace ChiWalker.Routines.Monk
{
    internal class Brewmaster
    {
        private static WoWUnit BlackOxStatue
        {
            get
            {
                return
                    ObjectManager.GetObjectsOfType<WoWUnit>().FirstOrDefault(
                        u => u.Distance <= 40f && u.Entry == 61146 && u.SummonedByUnitGuid == StyxWoW.Me.Guid);
            }
        }

        [Behavior(BehaviorType.Combat)]
        [Spec(WoWSpec.MonkBrewmaster)]
        [Class(WoWClass.Monk)]
        public static Composite BrewmasterMonk()
        {
            return
                new PrioritySelector(
                    Safers.EnsureTarget(),
                    WaitFor.WaitForCast(),
                    Movement.MoveToLoS(ret => StyxWoW.Me.CurrentTarget),
                    Movement.MoveToUnit(ret => StyxWoW.Me.CurrentTarget),
                    Movement.FaceMyTarget(),
                    new CastOnUnit(Spell.SpearHandStrike, ret => StyxWoW.Me.CurrentTarget,
                        ret =>
                            StyxWoW.Me.CurrentTarget.CanInterruptCurrentSpellCast &&
                            StyxWoW.Me.CurrentTarget.IsCasting),
                    new CastOnUnit(Spell.BlackoutKick, ret => StyxWoW.Me.CurrentTarget,
                        ret => StyxWoW.Me.GetAuraTimeLeft("Shuffle", true).TotalSeconds < 5),
                    new CastAtLocation(Spell.SummonBlackOxStatue, ret => StyxWoW.Me.Location,
                        ret =>
                            ChiWalkerSettings.Instance.Monk.UseOxStatue && BlackOxStatue == null &&
                            (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid)
                        ),
                    new CastOnUnit(Spell.TouchOfDeath, ret => StyxWoW.Me.CurrentTarget,
                        ret =>
                            StyxWoW.Me.HasAura("Death Note") && StyxWoW.Me.CurrentTarget.HealthPercent > 10 &&
                            StyxWoW.Me.CurrentTarget.HealthPercent < StyxWoW.Me.HealthPercent),
                    new CastOnMyTarget(Spell.ChargingOxWave, ret =>
                        Clusters.GetClusterCount(StyxWoW.Me,
                            Clusters.NearbyUnfriendlyUnits,
                            ClusterType.Cone,
                            8f) >= 2),
                    new CastOnSelf(Spell.LegSweep,
                        ret =>
                            Clusters.GetClusterCount(StyxWoW.Me, Clusters.NearbyUnitsInCombatWithMe,
                                ClusterType.Radius, 6f) > 2),
                    new CastOnMyTarget(Spell.BreathofFire,
                        ret =>
                            Clusters.GetClusterCount(StyxWoW.Me, Clusters.NearbyUnfriendlyUnits,
                                ClusterType.Cone,
                                8f) >= 2),
                    new CastOnUnit(Spell.KegSmash, ret => StyxWoW.Me.CurrentTarget),
                    new CastOnMyTarget(Spell.SpinningCraneKick,
                        ret =>
                            Clusters.GetClusterCount(StyxWoW.Me, Clusters.NearbyUnitsInCombatWithMe,
                                ClusterType.Radius, 8f) > 2),
                    new CastOnMyTarget(Spell.ChiWave, ret => StyxWoW.Me.HealthPercent <= 90),
                    new CastOnMyTarget(Spell.ChiBurst, ret => StyxWoW.Me.HealthPercent <= 90),
                    new CastOnUnit(Spell.Jab, ret => StyxWoW.Me.CurrentTarget, ret => StyxWoW.Me.CurrentChi <= 4),
                    new CastOnUnit(Spell.BlackoutKick, ret => StyxWoW.Me.CurrentTarget),
                    new CastOnUnit(Spell.TigerPalm, ret => StyxWoW.Me.CurrentTarget)
                    );
        }

        [Behavior(BehaviorType.Pull)]
        [Spec(WoWSpec.MonkBrewmaster)]
        [Class(WoWClass.Monk)]
        public static Composite BrewmasterMonkPull()
        {
            return
                new PrioritySelector(
                    Safers.EnsureTarget(),
                    new CastAtLocation(Spell.DizzyingHaze, ret => StyxWoW.Me.CurrentTarget.Location,
                        ret => ChiWalkerSettings.Instance.Monk.UseDizzyingHaze),
                    new CastOnUnit(Spell.Clash, ret => StyxWoW.Me.CurrentTarget,
                        ret => StyxWoW.Me.CurrentTarget.Distance > 8f),
                    new CastOnUnit(Spell.Provoke, ret => StyxWoW.Me.CurrentTarget),
                    new CastOnUnit(Spell.Jab, ret => StyxWoW.Me.CurrentTarget),
                    Movement.MoveToUnit(ret => StyxWoW.Me.CurrentTarget)
                    );
        }

        [Behavior(BehaviorType.PreCombatBuffs | BehaviorType.CombatBuffs)]
        [Spec(WoWSpec.MonkBrewmaster)]
        [Class(WoWClass.Monk)]
        public static Composite BrewmasterMonkBuff()
        {
            return
                new Decorator(ret => !StyxWoW.Me.Mounted,
                    new PrioritySelector(
                        new CastOnSelf(Spell.StanceoftheSturdyOx,
                            ret => !StyxWoW.Me.HasAura("Stance of the Sturdy Ox")),
                        new NoGCDSpell(Spell.FortifyingBrew, ret => StyxWoW.Me,
                            ret =>
                                StyxWoW.Me.HealthPercent <=
                                ChiWalkerSettings.Instance.Monk.ForifyingBrewHealth,
                            false
                            ),
                        new CastOnSelf(Spell.ExpelHarm,
                            ret =>
                                StyxWoW.Me.HealthPercent <=
                                ChiWalkerSettings.Instance.Monk.ExpelHarmHealth),
                        new NoGCDSpell(Spell.PurifyingBrew,
                            ret => StyxWoW.Me,
                            ret =>
                                StyxWoW.Me.HasAura("Moderate Stagger") ||
                                StyxWoW.Me.HasAura("Heavy Stagger"),
                            true),
                        new CastOnSelf(Spell.DampenHarm, ret => StyxWoW.Me.HealthPercent <= 60),
                        new CastOnSelf(Spell.Guard,
                            ret =>
                                StyxWoW.Me.HealthPercent <=
                                ChiWalkerSettings.Instance.Monk.GuardHealth &&
                                StyxWoW.Me.CurrentChi >= 2),
                        new NoGCDSpell(Spell.ElusiveBrew,
                            ret => StyxWoW.Me,
                            ret =>
                                StyxWoW.Me.HealthPercent <=
                                ChiWalkerSettings.Instance.Monk.ElusiveBrewHealth &&
                                StyxWoW.Me.HasAura(128939) &&
                                StyxWoW.Me.GetAuraById(128939).StackCount >=
                                ChiWalkerSettings.Instance.Monk.ElusiveBrewStacks,
                            true),
                        new CastOnSelf(Spell.TigersLust, ret => StyxWoW.Me.IsImmobilized()),
                        new CastOnSelf(Spell.ChiBrew, ret => StyxWoW.Me.CurrentChi < 4),
                        new CastOnMyTarget(Spell.InvokeXuen,
                            ret =>
                                SettingsAnalyizer.AnalizeSpellUsage(
                                    ChiWalkerSettings.Instance.Monk.InvokeXuen)),
                        Group.BuffKings()
                        ));
        }
    }
}